#pragma once


/// environment detection
#if !defined(WINDOWS) && (defined(_WINDOWS) || defined(WIN32) || defined(_WIN32) || defined(_MSC_VER))
#define WINDOWS
#endif
///



/// main platform headers
#if defined(WINDOWS)
#pragma warning(disable: 4200) //warning C4200: nonstandard extension used : zero-sized array in struct/union. Cannot generate copy-ctor or copy-assignment operator when UDT contains a zero-sized array.
#pragma warning(disable: 4996) //warning C4996: '%s': This function or variable may be unsafe. Consider using %s_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS.
#define WIN32_LEAN_AND_MEAN
#define WIN32_NO_STATUS
#define _WINSOCKAPI_
#include <windows.h>
#undef WIN32_NO_STATUS
#undef _WINSOCKAPI_
#include <ntstatus.h>
#include <winternl.h>
#endif
///


/// standard C stuff
#include <stdarg.h>
#include <stddef.h>
#include <stdlib.h>
#include <sys/types.h>
#if defined(WINDOWS)
#define snprintf _snprintf
typedef SSIZE_T ssize_t;
#endif
///


/// string juggling
#include <string.h>
#if defined(WINDOWS)
#define strdup _strdup
#define stricmp _stricmp
#define wcsicmp _wcsicmp
#define strnicmp _strnicmp
#define wcsnicmp _wcsnicmp
#define strcasecmp _stricmp
#define strncasecmp _strnicmp
#if defined(_MSC_VER) && _MSC_VER < 1400
size_t strnlen(const char* string, size_t maxlen);
#endif
#else //non-WINDOWS
#define stricmp strcasecmp
#define strnicmp strncasecmp
#endif
///


/// stdint
#if defined(_MSC_VER)
#include <basetsd.h>
typedef INT8  int8_t;
typedef INT16 int16_t;
typedef INT32 int32_t;
typedef INT64 int64_t;
typedef UINT8  uint8_t;
typedef UINT16 uint16_t;
typedef UINT32 uint32_t;
typedef UINT64 uint64_t;
typedef INT_PTR intptr_t;
typedef UINT_PTR uintptr_t;
#else //non-MSVC
#include <stdint.h>
#endif
///


/// filesystem
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#if defined(WINDOWS)
#include <direct.h>
#include <io.h>
#include <fcntl.h>
#if defined(_MSC_VER)
int ftruncate(int fd, unsigned int length);
#endif
#else //non-WINDOWS
#include <unistd.h>
#endif
///


/// networking
#if defined(WINDOWS)
#include <winsock2.h>
#else //non-WINDOWS
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define SOCKET_ERROR (-1)
#endif
///


/// process
#if defined(WINDOWS)
#include <process.h>
#define getpid _getpid
#else //non-WINDOWS
#include <unistd.h>
#endif
///


/// safe ctype operations
#include <ctype.h>
#define ISALNUM(c) (isalnum((unsigned char)(c)))
#define ISALPHA(c) (isalpha((unsigned char)(c)))
#define ISCNTRL(c) (iscntrl((unsigned char)(c)))
#define ISDIGIT(c) (isdigit((unsigned char)(c)))
#define ISGRAPH(c) (isgraph((unsigned char)(c)))
#define ISLOWER(c) (islower((unsigned char)(c)))
#define ISPRINT(c) (isprint((unsigned char)(c)))
#define ISPUNCT(c) (ispunct((unsigned char)(c)))
#define ISSPACE(c) (isspace((unsigned char)(c)))
#define ISUPPER(c) (isupper((unsigned char)(c)))
#define ISXDIGIT(c) (isxdigit((unsigned char)(c)))
#define TOASCII(c) (toascii((unsigned char)(c)))
#define TOLOWER(c) (tolower((unsigned char)(c)))
#define TOUPPER(c) (toupper((unsigned char)(c)))
///


/// C_ASSERT() macro
#if !defined(C_ASSERT)
#if defined(_MSC_VER)
#include <windows.h> //-> winnt.h
#else
#define C_ASSERT(e) typedef char __C_ASSERT__[(e)?1:-1]
#endif
#endif
///


/// useful macros
#define ARRAYLENGTH(x) ( sizeof(x) / sizeof((x)[0]) )
#define ALIGN(x,n) ( (x) + ((n) - (x) % (n)) % (n) )
///


/// disable attributed stuff on non-GNU
#if !defined(__GNUC__) && !defined(MINGW)
#define  __attribute__(x)
#endif
///


/// alias std::tr1 into std
namespace std { namespace tr1 { }; using namespace std::tr1; }
///
